﻿using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;

namespace CPTY
{
    public class Cmd
    {
        double R;
        double x;
        double y;

        private float DegreesToRadians(float deg)
        {
            return deg * (float)Math.PI / 180.0f;
        }

        [CommandMethod("cpty")]
        public void Ddd()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = acDoc.Editor;

            PromptPointResult center = ed.GetPoint("指定投影的圆心:");
            PromptDoubleResult rad = ed.GetDouble("指定投影圆半径");

            if (center.Status != PromptStatus.OK || rad.Status != PromptStatus.OK)
            {
                return;
            }

            R = rad.Value;
            x = center.Value.X;
            y = center.Value.Y;

            List<Entity> ents = new List<Entity>();
        
            Transaction trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
            BlockTableRecord btr = (BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId, OpenMode.ForWrite);
                       
            ents.Add(new Circle(new Point3d(x, y, 0), Vector3d.ZAxis, R));
            //for (int i = 1;i<9;i++)
            //{
            //    double A = DegreesToRadians(i * 10);
            //    double a = DegreesToRadians((45f - 10f * i / 2f));
            //    double ob = (R * Math.Tan(a));
            //    double rr = (ob * ob + R * R) / (2.0 * ob);
            //    double rrr = rr - ob;
            //    double aa = Math.Atan(rrr / R);

            //    ents.Add(new Arc(new Point3d(x + rrr, y, 0), 
            //        Vector3d.ZAxis, rr, Math.PI / 2f + aa, 3 * Math.PI / 2f - aa));
            //    ents.Add(new Arc(new Point3d(x - rrr, y, 0), 
            //        Vector3d.ZAxis, rr, 3 * Math.PI / 2f + aa, Math.PI / 2f - aa));    

            //    double cos = Math.Cos(A);
            //    double hr = (R * R + ob * ob - cos * 2.0 * R * ob) / (cos * 2.0 * R - 2.0 * ob);

            //    ents.Add(new Arc(new Point3d(x, y + ob + hr, 0), Vector3d.ZAxis, hr, Math.PI + A, -A));
            //    ents.Add(new Arc(new Point3d(x, y - ob - hr, 0), Vector3d.ZAxis, hr, A, Math.PI - A));
            //}

            //ents.Add(new Line(new Point3d(x, y - R, 0), new Point3d(x, y + R, 0)));
            //ents.Add(new Line(new Point3d(x - R, y, 0), new Point3d(x + R, y, 0)));

            foreach (Entity ent in ents)
            {
                btr.AppendEntity(ent);
                trans.AddNewlyCreatedDBObject(ent, true);
            }

            trans.Commit();         
            trans.Dispose();
        }

        [CommandMethod("tycz")]
        public void Dad()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;      
            Editor ed = acDoc.Editor;

            PromptIntegerResult dip = ed.GetInteger("输入倾向:");
            PromptIntegerResult dip_angle = ed.GetInteger("输入倾角:");

            if (dip.Status == PromptStatus.OK && dip_angle.Status == PromptStatus.OK)
            {
                int dip_v = dip.Value;
                int dip_angle_v = dip_angle.Value;     

                Entity ent;

                var a1 = DegreesToRadians(-dip_v);
                var x1 = x + (float)Math.Sin(a1) * R;
                var y1 = y + (float)Math.Cos(a1) * R;

                var a2 = (float)Math.PI - DegreesToRadians(dip_v);
                var x2 = x + (float)Math.Sin(a2) * R;
                var y2 = y + (float)Math.Cos(a2) * R;

                if (Math.Abs(90.0 - dip_angle_v) < 10e-5)
                {                    
                    ent = new Line(new Point3d(x1, y1, 0), new Point3d(x2, y2, 0));
                }
                else
                {
                    var a = DegreesToRadians((45f - dip_angle_v / 2f));
                    var ob = (R * (float)Math.Tan(a));  

                    double rr = (ob * ob + R * R) / (2.0 * ob);
                    double rrr = rr - ob;
                    double aa = Math.Atan(rrr / R);

                    ent = new Arc(new Point3d(x - rrr, y, 0),
                        Vector3d.ZAxis, rr, 3 * Math.PI / 2f + aa, Math.PI / 2f - aa);

                    double rotationAngle = DegreesToRadians((90 - dip_v));

                    Matrix3d mt = Matrix3d.Rotation(rotationAngle, Vector3d.ZAxis, new Point3d(x, y, 0));
                    var eee = ent as Entity;
                    if (eee != null)
                    {
                        ent = eee.GetTransformedCopy(mt);
                    }
                }
                
                if (ent != null)
                {
                    Transaction trans =
                        HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
                    BlockTableRecord btr =
                        (BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId,
                        OpenMode.ForWrite);
                    btr.AppendEntity(ent);
                    trans.AddNewlyCreatedDBObject(ent, true);
                    trans.Commit();
                    trans.Dispose();
                }               
            }
        }
    }
}
